<?php

namespace plugin\admin\app\common\alibabacloud\dysms;

use plugin\admin\app\constant\v1\CommonConstant;
use plugin\admin\app\service\v1\OptionService;

class Api
{

    // 保存错误信息
    public $error;

    public function __construct($cofig = [])
    {

    }

    /**
     * 模板短信发送
     *
     * @param string $mobile
     * @param string $code
     * @param string $event
     */
    public function send($mobile, $code, $event)
    {
        $msg = '【短信配置】 ';
        $config = OptionService::getConfig('sms');
        if ($event == CommonConstant::SMS_0) {
            $templateCode = $config['alisms_template_code_1'];
        }
        if ($event == CommonConstant::SMS_1) {
            $templateCode = $config['alisms_template_code_2'];
        }

        $params = [   //此处作了修改
            'SignName' => $config['alisms_sign_name'],
            'Format' => 'JSON',
            'Version' => '2017-05-25',
            'AccessKeyId' => $config['alisms_username'],
            'SignatureVersion' => '1.0',
            'SignatureMethod' => 'HMAC-SHA1',
            'SignatureNonce' => uniqid(),
            'Timestamp' => gmdate('Y-m-d\TH:i:s\Z'),
            'Action' => 'SendSms',
            'TemplateCode' => $templateCode,
            'PhoneNumbers' => $mobile,
            //'TemplateParam' => $verify_code
            'TemplateParam' => '{"code":"' . $code . '"}'
            //'TemplateParam' => '{"time":"1234"}'   //更换为自己的实际模版
        ];
        // 计算签名并把签名结果加入请求参数
        $params ['Signature'] = $this->computeSignature($params, $config['alisms_password']);
        // 发送请求（此处作了修改）
        //$url = 'https://sms.aliyuncs.com/?' . http_build_query ( $params );
        $url = 'http://dysmsapi.aliyuncs.com/?' . http_build_query($params);

        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($curl, CURLOPT_TIMEOUT, 10);
        // 执行请求并获取响应
        $response = curl_exec($curl);
        // 检查错误
        if (curl_errno($curl)) {
            return V(1, $msg.'请求错误: ' . curl_error($curl));
        }
        // 关闭cURL资源
        curl_close($curl);

        $result = json_decode($response, true);
        if ($result['Code'] != 'OK') {
            return V(1, $msg.$this->getErrorMessage($result['Code']));
        }
        return V(0, $result['Code']);
    }

    /**
     * 签名
     *
     * @param array $parameters
     * @param string $accessKeySecret
     * @return string
     */
    public function computeSignature($parameters, $accessKeySecret)
    {
        ksort($parameters);
        $canonicalizedQueryString = '';
        foreach ($parameters as $key => $value) {
            $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value);
        }
        $stringToSign = 'GET&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1));
        $signature = base64_encode(hash_hmac('sha1', $stringToSign, $accessKeySecret . '&', true));
        return $signature;
    }

    public function percentEncode($string)
    {
        $string = urlencode($string);
        $string = preg_replace('/\+/', '%20', $string);
        $string = preg_replace('/\*/', '%2A', $string);
        $string = preg_replace('/%7E/', '~', $string);
        return $string;
    }

    /**
     * 获取详细错误信息
     *
     * @param string $code
     * @return string 错误描述信息
     */
    public function getErrorMessage($code)
    {
        // 阿里云的短信 乱八七糟的(其实是用的阿里大于)
        // https://api.alidayu.com/doc2/apiDetail?spm=a3142.7629140.1.19.SmdYoA&apiId=25450
        // API错误码
        // https://help.aliyun.com/zh/sms/developer-reference/api-error-codes?spm=a2c4g.11186623.help-menu-44282.d_5_5.10b4c956sfjZhh&scm=20140722.H_101346._.OR_help-T_cn~zh-V_1
        $message = [
            // 签名相关错误
            'isv.SMS_SIGNATURE_SCENE_ILLEGAL' => '签名和模板类型不一致',
            'isv.SMS_SIGNATURE_ILLEGAL' => '该账号下找不到对应签名',
            'isv.SMS_SIGN_ILLEGAL' => '签名禁止使用',
            'isv.SIGN_COUNT_OVER_LIMIT' => '超过单自然日签名申请数量上限',
            'isv.SIGN_NAME_ILLEGAL' => '签名名称不符合规范',
            'isv.SIGN_FILE_LIMIT' => '签名认证材料附件大小超过限制',
            'isv.SIGN_OVER_LIMIT' => '签名字符数量超过限制',
            'SIGNATURE_BLACKLIST' => '签名内容涉及违规信息',
            'isv.ERROR_SIGN_NOT_DELETE' => '审核中的签名，暂时无法删除',
            'isv.ERROR_SIGN_NOT_MODIFY' => '已通过的签名不支持修改',
            'isv.SIGN_SOURCE_ILLEGAL' => '签名来源不支持',
            'isv.SMS_SIGN_EMOJI_ILLEGAL' => '签名不能包含emoji表情',

            // 模板相关错误
            'isv.SMS_TEMPLATE_ILLEGAL' => '请检查模板内容与模板参数是否匹配',
            'isv.TEMPLATE_COUNT_OVER_LIMIT' => '超过单自然日模板申请数量上限',
            'isv.TEMPLATE_OVER_LIMIT' => '模板字符数量超过限制',
            'isv.ERROR_TEMPLATE_NOT_DELETE' => '审核中的模板，暂时无法删除',
            'isv.ERROR_TEMPLATE_NOT_MODIFY' => '已通过的模板不支持修改',
            'template_parameter_count_illegal' => '验证码模板仅支持一个验证码作为变量',

            // 扩展码相关错误
            'isv.EXTEND_CODE_ERROR' => '扩展码使用错误，相同的扩展码不可用于多个签名',
            'isv.ONE_CODE_MULTIPLE_SIGN' => '一码多签',
            'isv.CODE_EXCEED_LIMIT' => '自拓扩展码个数已超过上限',
            'isv.CODE_ERROR' => '传入扩展码不可用',

            // 手机号码相关错误
            'isv.MOBILE_NUMBER_ILLEGAL' => '手机号码格式错误',
            'isv.MOBILE_COUNT_OVER_LIMIT' => '手机号码数量超出限制',
            'isv.DOMESTIC_NUMBER_NOT_SUPPORTED' => '国际/港澳台消息模板不支持发送境内号码',
            'isv.PHONENUMBERS_OVER_LIMIT' => '上传手机号个数超过上限',

            // 参数相关错误
            'isv.INVALID_PARAMETERS' => '参数格式不正确',
            'isv.INVALID_JSON_PARAM' => '参数格式错误，请修改为字符串值',
            'isv.PARAM_LENGTH_LIMIT' => '参数超过长度限制',
            'isv.PARAM_NOT_SUPPORT_URL' => '变量不支持传入URL',
            'isv.TEMPLATE_MISSING_PARAMETERS' => '模板变量中存在未赋值变量',
            'isv.TEMPLATE_PARAMS_ILLEGAL' => '传入的变量内容和实际申请模板时变量所选择的属性不配',
            'PARAMS_ILLEGAL' => '参数错误',

            // 内容相关错误
            'isv.SMS_CONTENT_ILLEGAL' => '短信内容包含禁止发送内容',
            'isv.UNSUPPORTED_CONTENT' => '不支持的短信内容',
            'isv.SMS_CONTENT_MISMATCH_TEMPLATE_TYPE' => '短信内容和模板属性不匹配',
            'CONTENT_KEYWORD' => '内容关键字拦截',
            'CONTENT_ERROR' => '内容无退订',

            // 限额控制相关
            'isv.DAY_LIMIT_CONTROL' => '触发日发送限额',
            'isv.MONTH_LIMIT_CONTROL' => '触发月发送限额',
            'isv.BUSINESS_LIMIT_CONTROL' => '触发云通信流控限制',
            'isv.BLACK_KEY_CONTROL_LIMIT' => '黑名单管控',

            // 账户相关错误
            'isv.ACCOUNT_NOT_EXISTS' => '账户不存在',
            'isv.ACCOUNT_ABNORMAL' => '账户异常',
            'isv.AMOUNT_NOT_ENOUGH' => '账户余额不足',
            'isv.OUT_OF_SERVICE' => '业务停机',
            'isv.PRODUCT_UN_SUBSCRIPT' => '未开通云通信产品的阿里云客户',
            'isv.PRODUCT_UNSUBSCRIBE' => '产品未开通',
            'isv.SECURITY_FROZEN_ACCOUNT' => '账号因安全问题被冻结',

            // 权限相关
            'isp.RAM_PERMISSION_DENY' => 'RAM权限不足',

            // IP相关
            'isv.DENY_IP_RANGE' => '原IP地址所在的地区被禁用',

            // 系统错误
            'isp.SYSTEM_ERROR' => '系统出现错误，请重新调用',
            'isp.GATEWAY_ERROR' => '调用发送应用模块失败',

            // 签名验证相关
            'SignatureDoesNotMatch' => '客户端生成的签名与服务端不匹配',
            'InvalidTimeStamp.Expired' => '时间戳或日期已过期',
            'SignatureNonceUsed' => '签名随机数已被使用',
            'InvalidVersion' => 'API版本号错误',
            'InvalidAction.NotFound' => '未找到指定的API，请检查您的URL和方法',

            // 短链相关
            'isv.SHORTURL_OVER_LIMIT' => '超过单自然日短链申请数量上限',
            'isv.NO_AVAILABLE_SHORT_URL' => '该账号无有效短链',
            'isv.SHORTURL_NAME_ILLEGAL' => '短链名不能超过13字符',
            'isv.SOURCEURL_OVER_LIMIT' => '原始链接字符数量超过限制',
            'isv.SHORTURL_TIME_ILLEGAL' => '短链有效期期限超过限制',
            'isv.SHORTURL_STILL_AVAILABLE' => '原始链接生成的短链仍在有效期内',
            'isv.SHORTURL_DOMAIN_EMPTY' => '短链创建失败，请先提交域名报备',

            // 文件相关
            'isv.ERROR_EMPTY_FILE' => '签名文件为空',

            // 测试相关
            'isv.SMS_TEST_SIGN_TEMPLATE_LIMIT' => '测试模板和签名限制',
            'isv.SMS_TEST_TEMPLATE_PARAMS_ILLEGAL' => '测试专用模板中的变量仅支持4~6位纯数字',
            'isv.SMS_TEST_NUMBER_LIMIT' => '只能向已绑定的手机号发送',

            // 运营商相关错误
            'MOBILE_NOT_ON_SERVICE' => '停机、空号、暂停服务、关机、不在服务区',
            'MOBILE_SEND_LIMIT' => '单个号码日、月发送上限，流控超限，频繁发送超限',
            'MOBILE_ACCOUNT_ABNORMAL' => '用户账户异常、携号转网、欠费等',
            'MOBILE_IN_BLACK' => '手机号在黑名单',
            'MOBLLE_TERMINAL_ERROR' => '手机终端问题、内存满、SIM卡满、非法设备等',
            'INVALID_NUMBER' => '号码状态异常',
            'REQUEST_SUCCESS' => '请求成功（平台接到请求，但未接收到运营商侧的回执状态）',
            'SP_NOT_BY_INTER_SMS' => '未开通国际短信',
            'SP_UNKNOWN_ERROR' => '运营商未知错误',
            'USER_REJECT' => '接收用户已退订此业务或产品未开通',
            'NO_ROUTE' => '当前短信内容无可用通道发送',
            'PORT_NOT_REGISTERED' => '当前使用端口号尚未完成企业实名制报备流程',

            // 其他错误
            'isv.SMS_OVER_LIMIT' => '单日最多申请模板或签名100条',
            'isv.CUSTOMER_REFUSED' => '用户已退订推广短信',
            'IS_CLOSE' => '短信下发时通道被关停',

            'InvalidDayuStatus.Malformed' => '账户短信开通状态不正确',
            'InvalidSignName.Malformed' => '短信签名不正确或签名状态不正确',
            'InvalidTemplateCode.MalFormed' => '短信模板Code不正确或者模板状态不正确',
            'InvalidRecNum.Malformed' => '目标手机号不正确，单次发送数量不能超过100',
            'InvalidParamString.MalFormed' => '短信模板中变量不是json格式',
            'InvalidParamStringTemplate.Malformed' => '短信模板中变量与模板内容不匹配',
            'InvalidSendSms' => '触发业务流控',
            'InvalidDayu.Malformed' => '变量不能是url，可以将变量固化在模板中'
        ];

        // 将code转换为字符串进行查找
        $codeStr = (string)$code;
        if (isset($message[$codeStr])) {
            return $message[$codeStr];
        }

        // 如果没找到，返回原始错误码
        return "未知错误码: {$codeStr}";
    }
}